using System;
using System.Configuration;
using System.DirectoryServices;
using System.Security.Principal;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;

using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using Microsoft.SharePoint.Utilities;

using EAT.Common;

namespace ECTSExtension
{
    public class ExternalUserRequest : LayoutsPageBase
    {

        //
        // The web page user enters the user name into the TextBox
        // tbUsername.
        //
        protected System.Web.UI.WebControls.TextBox tbUsername;

        protected TextBox tbFirstName;
        protected TextBox tbLastName;
        protected TextBox tbService;
        protected TextBox tbTelephone;
        protected TextBox tbTitleRank;
        protected TextBox tbJustification;

        //
        // The user clicks the Button btnLookup to query the Membership 
        // directory for the existence of the user specified in tbUsername.
        //
        protected System.Web.UI.WebControls.ImageButton btnLookup;

        //
        // The results of the lookup appear in the Label lblLookupResult.
        //
        protected System.Web.UI.WebControls.Label lblLookupResult;

        //
        // If the user does not exist, the the LinkButton lnkProvision
        // becomes visible, and allows the web site user to initiate
        // the external user provisioning process.
        //
        protected System.Web.UI.WebControls.LinkButton lnkProvision;

        //
        // The Label lblProvision displays the results of the provisioning
        // request.
        //
        protected System.Web.UI.WebControls.Label lblProvision;

        protected bool bWorkFlowEnabled = false;
        private SqlManager SqlM;

        public ExternalUserRequest()
        {
            SqlM = new SqlManager();
        }


        protected override void OnLoad(EventArgs e)
        {
            if (SqlM.GetEntry("Config", "UACWorkflowApprovers") == null ||
                SqlM.GetEntry("Config", "UACWorkflowApprovers") == "")
            {
                bWorkFlowEnabled = false;
            }
            else
            {
                bWorkFlowEnabled = true;
            }
        }

        protected void btnLookup_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(tbUsername.Text))
            {
                lblLookupResult.Text = "You must provide your e-mail to verify it is not already in use.";
            }
            else
            {
                //
                // Hide the provision link button and clean the label text.
                //
                lnkProvision.Visible = false;
                lblProvision.Text = null;

                ExtendedUserManager um = new ExtendedUserManager(
                                          );

                if (um.IsValidUsername(tbUsername.Text) == false)
                {
                    throw new SystemException("Username was not valid");
                }

                try
                {
                    MembershipUser user = null;

                    SPSecurity.RunWithElevatedPrivileges(
                        delegate()
                        {
                            user = Membership.GetUser(tbUsername.Text);
                        }
                    );

                    if (user != null)
                    {
                        lblLookupResult.Text = "This e-mail address is already in use<br/>";
                        try
                        {
                            string supportemail = ConfigurationManager.AppSettings["SupportEmail"].ToString();
                            lblLookupResult.Text += "If you have already requested a KnIFE or JCREW account with this e-mail address click ";
                            lblLookupResult.Text += string.Format("<a href=\"mailto:{0}?Subject=Site Access Request&body=Requested Account: {1}%0A[Additional Request Information?]\">here</a>.", 
                                supportemail, tbUsername.Text);
                        }
                        catch { }
                    }
                    else
                    {
                        lnkProvision.Visible = true;
                        tbFirstName.Visible = true;
                        tbLastName.Visible = true;
                        tbService.Visible = true;
                        tbTelephone.Visible = true;
                        tbTitleRank.Visible = true;
                        tbJustification.Visible = true;
                    }
                }
                catch (Exception ex)
                {
                    lblLookupResult.Text += ex.Message;
                }
            }
        }

        protected void lnkProvision_Click(object sender, EventArgs e)
        {
            if (string.IsNullOrEmpty(tbFirstName.Text) ||
                string.IsNullOrEmpty(tbLastName.Text) ||
                string.IsNullOrEmpty(tbService.Text) ||
                string.IsNullOrEmpty(tbTelephone.Text) ||
                string.IsNullOrEmpty(tbTitleRank.Text))
            {
                lblLookupResult.Text = "You must provide information for ALL fields";
                lnkProvision.Visible = true;
                tbFirstName.Visible = true;
                tbLastName.Visible = true;
                tbService.Visible = true;
                tbTelephone.Visible = true;
                tbTitleRank.Visible = true;
                tbJustification.Visible = true;
            }
            else
            {
                try
                {
                    //
                    // Instantiate a UserManager and connect to the LDAP server.
                    //
                    ExtendedUserManager um = new ExtendedUserManager(
                                              ConfigurationManager.ConnectionStrings["ADAMConnectionString"].ConnectionString
                                              );

                    if (um.IsValidUsername(tbUsername.Text) == false)
                    {
                        throw new NotSupportedException("Username is not valid");
                    }

                    MembershipCreateStatus status;

                    //
                    // Create the user with the new password.  Use a sentinel value for the 
                    // secret password.  If workflow is enabled, then create the user in a 
                    // disabled state.
                    //
                    string createUserProvider = string.Empty;

                    try
                    {
                        MembershipUser user = null;
                        string password = Membership.GeneratePassword(9, 2);
                        MembershipProvider provider = null;
                        try
                        {
                            createUserProvider = ConfigurationManager.AppSettings["CreateUserMembershipProvider"].ToString();
                            provider = Membership.Providers[createUserProvider];
                        }
                        catch
                        {
                            createUserProvider = "Default Provider";
                            provider = Membership.Provider;
                        }

                        SPSecurity.RunWithElevatedPrivileges(
                            delegate()
                            {
                                user = Membership.CreateUser(
                                    tbUsername.Text,
                                    password,
                                    tbUsername.Text,
                                    "[change the secret question]",
                                    Membership.GeneratePassword(9, 2),
                                    !bWorkFlowEnabled,
                                    out status);

                                um.SetProfileInformation(user, tbService.Text, tbFirstName.Text, tbLastName.Text, tbTelephone.Text);

                                //
                                // Store the account requester in the LDAP store.
                                //
                                um.SetProvisioner(tbUsername.Text, SqlM.GetEntry("Config", "eMailSource"));

                                try
                                {
                                    using (DirectoryEntry deUser = um.FindUser(tbUsername.Text))
                                    {
                                        deUser.Properties["title"].Value = tbTitleRank.Text;
                                        deUser.Properties["comment"].Value = tbJustification.Text;
                                        deUser.CommitChanges();
                                    }
                                }
                                catch { lblLookupResult.Text += "<br/>Failed to set User's Title / Rank or Justification / Reason";  }
                            }
                        );
                        SendEmail(tbUsername.Text);
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }

                    //
                    // Hide the provision link.
                    // Clear the text describing the success / failure of the initial 
                    // lookup operation.
                    //
                    lnkProvision.Visible = false;
                    tbUsername.Text = null;
                    lblLookupResult.Text = "Your account request has been completed.";

#if (debug == true)
                    lblLookupResult.Text += "<br/>Account Creation Used Provider " + createUserProvider + "<br/>";
#endif
                    tbFirstName.Text = null;
                    tbLastName.Text = null;
                    tbService.Text = null;
                    tbTelephone.Text = null;
                    tbTitleRank.Text = null;
                }
                catch (Exception ex)
                {
                    lblLookupResult.Text += "<br/>Attempt to request account failed.<br/>If this problem persists please contact technical support.<br/>";
                    try
                    {
                        string supportemail = ConfigurationManager.AppSettings["SupportEmail"].ToString();
                        lblLookupResult.Text += string.Format("<br/>Click <a href=\"mailto:{0}?Subject=Account%20Request%20Error&body=Account Requested:{1}%0A{2}%0A{3}\">Here</a> to e-mail the error to support",
                            supportemail, tbUsername.Text, ex.Message, ex.StackTrace);
                    }
                    catch { }
                }
            }
        }

        private void SendEmail(string sendToEmail)
        {
            SPUtility.SendEmail(SPContext.Current.Web, false, false,
                sendToEmail, "Your Account Request",
                "<p>Your request for an account has been received and you will be notification when it has been approved or denied.</p>");
        }
    }
}
